自制APP连接OneNET 您所在的位置:网站首页 onenet studio干啥用 自制APP连接OneNET

自制APP连接OneNET

2023-09-19 15:17| 来源: 网络整理| 查看: 265

文章目录 前言一、前期准备二、功能介绍1、自制APP页面展示 三、使用SSCOM串口助手连接OneNET1、串口助手配置2、新增数据流3、查询数据流4、删除数据流5、查询历史数据6、更新触发器 四、STM32功能实现1、修改OneNET官方提供的例程2、从OneNET平台获取数据3、下发命令的处理 五、手机APP制作1、页面布局2、连接OneNET云平台3、查询数据流4、开关灯控制5、其他功能 总结

前言

本案例主要是实现使用自制的手机APP对OneNET云平台上的数据查看和下发命令控制单片机上的小灯(PC13)亮灭,使用的HTTP协议接入OneNET,APP开发使用的是E4A中文安卓编程。

一、前期准备

1、STM32F103C8T6最小系统板 2、ESP8266-01S模块 3、在OneNET平台上创建HTTP协议的产品和设备 4、安装E4A软件,软件不大几百兆下载链接

二、功能介绍 1、自制APP页面展示

(1)设备ID和Master-APIkey要更改为自己的 (2)查询数据流:可以查询两个数据流,点击查询后,每3S向平台获取一次数据。数据流的名字可以更改以获取不同的数据流的数据 (3)新增数据流:上传一个名为Temp数据流到OneNET平台,分别是数据流名字和数值 (4)删除数据流:删除名为TEST的数据流 (5)历史记录:查看数据流Temp从某日期某时间开始的20条数据 (6)更新触发器:要现在OneNET平台上设置触发器,第一个参数是触发器ID,当数据流Temp的值大于100时就会进通知用户,我这里使用的是邮件通知。 (7)开灯:打开和关闭板子上的小灯亮灭

在这里插入图片描述

视频演示: 上传后的视频有点模糊,将就着看吧。

自制APP连接OneNET

视频截图: 左边是OneNET云平台上面的数据流面板,中间是自制的APP,右边是串口助手接32单片机。 在这里插入图片描述

三、使用SSCOM串口助手连接OneNET

这部分是让大家快速了解本案例的核心内容,主要就是OneNET平台上的HTTP请求方式GET/POST的使用。

1、串口助手配置

设置端口号为TCPClient OneNET的HTTP服务器的IP地址为:183.230.40.33 端口号为:80 在这里插入图片描述 依次次发送如下指令

2、新增数据流

在OneNET平台指定设备ID下新增三个数据流,分别是Temp,Humi,KEY,后面跟着的是数据流的值, 24是数据包(,;Temp,26;Humi,60;KEY,1;)的长度大小 api-key:=08b33=G=KP8qxRoCYYrurN41yk=s 是Master-APIkey,可以在OneNET平台上获取

//新增数据流 POST http://api.heclouds.com/devices/699063374/datapoints?type=5 HTTP/1.1 api-key:=08b33=G=KP8qxRoCYYrurN41yk= Host:api.heclouds.com Content-Length:24 ,;Temp,26;Humi,60;KEY,1;

服务器返回信息

HTTP/1.1 200 OK Date: Sat, 14 May 2022 14:15:48 GMT Content-Type: application/json Content-Length: 26 Connection: keep-alive Server: Apache-Coyote/1.1 Pragma: no-cache {"errno":0,"error":"succ"} 3、查询数据流

查询OneNET上面特定设备ID下的名为Temp和Humi的数据流,查询多个数据流用逗号隔开

//查询多个数据流 GET http://api.heclouds.com/devices/699063374/datapoints?datastream_id=Temp,Humi HTTP/1.1 api-key:=08b33=G=KP8qxRoCYYrurN41yk= Host:api.heclouds.com (后面两个回车)

服务器返回信息

HTTP/1.1 200 OK Date: Sat, 14 May 2022 14:21:11 GMT Content-Type: application/json Content-Length: 211 Connection: keep-alive Server: Apache-Coyote/1.1 Pragma: no-cache {"errno":0,"data":{"count":2,"datastreams":[{"datapoints":[{"at":"2022-05-14 22:15:48.830","value":"26"}],"id":"Temp"},{"datapoints":[{"at":"2022-05-14 22:15:48.833","value":"60"}],"id":"Humi"}]},"error":"succ"} 4、删除数据流

删除OneNET平台上指定设备ID中名为Humi的数据流

DELETE http://api.heclouds.com/devices/699063374/datastreams/Humi HTTP/1.1 api-key:=08b33=G=KP8qxRoCYYrurN41yk= Host:api.heclouds.com (后面两个回车)

服务器返回信息

HTTP/1.1 200 OK Date: Sat, 14 May 2022 14:26:09 GMT Content-Type: application/json Content-Length: 26 Connection: keep-alive Server: Apache-Coyote/1.1 Pragma: no-cache {"errno":0,"error":"succ"} 5、查询历史数据

请求指定设备从2022年5月14日零点以来,数据流Temp的第1至第5条数据

GET http://api.heclouds.com/devices/699063374/datapoints?datastream_id=Temp&start=2022-05-14T00:00:00&limit=5 HTTP/1.1 api-key:=08b33=G=KP8qxRoCYYrurN41yk= Host:api.heclouds.com (后面两个回车)

服务器返回信息

HTTP/1.1 200 OK Date: Sat, 14 May 2022 14:31:35 GMT Content-Type: application/json Content-Length: 362 Connection: keep-alive Server: Apache-Coyote/1.1 Pragma: no-cache {"errno":0,"data":{"cursor":"411019_699063374_1652462674000","count":5,"datastreams":[{"datapoints":[{"at":"2022-05-14 00:44:33.379","value":"11"},{"at":"2022-05-14 00:56:30.122","value":"91"},{"at":"2022-05-14 01:08:23.547","value":"91"},{"at":"2022-05-14 01:11:02.599","value":"91"},{"at":"2022-05-14 01:14:34.183","value":"81"}],"id":"Temp"}]},"error":"succ"} 6、更新触发器

设置数据流Temp的数值大于100时通知用户

PUT http://api.heclouds.com/triggers/1596927 HTTP/1.1 api-key:=08b33=G=KP8qxRoCYYrurN41yk= Host: api.heclouds.com Content-Length:43 {"ds_id":"Temp","type":">","threshold":100}

服务器返回信息

HTTP/1.1 200 OK Date: Sat, 14 May 2022 14:33:49 GMT Content-Type: application/json Content-Length: 26 Connection: keep-alive Server: Apache-Coyote/1.1 Pragma: no-cache {"errno":0,"error":"succ"}

以上就是本案例用到是指令,更多详细内容可以看OneNET的开发文档点击链接进入

四、STM32功能实现

这部分主要做的是完成上传数据到OneNET平台和获取数据从OneNET平台

1、修改OneNET官方提供的例程

将例程修改成适合自己的板子、完成数据上传的功能即可,我用的是C8T6板子。

在这里插入图片描述 数据包的打包处理 我的数据打包形式如下,由于没有sht20温湿度传感器,这里我的温湿度使用了全局变量进行自增处理。这个函数的功能是将需要上传的数据打包成一定格式,然后将打包好的数据发送到云平台。

u8 temp = 0; u8 humi = 0; void OneNet_FillBuf(char *buf) { char text[32]; char buf1[128]; memset(text, 0, sizeof(text)); memset(buf1, 0, sizeof(buf1)); strcpy(buf1, ",;"); // memset(text, 0, sizeof(text)); // sprintf(text, "Temp,%.1f;", sht20_info.tempreture); // strcat(buf1, text); // // memset(text, 0, sizeof(text)); // sprintf(text, "Humi,%.1f;",sht20_info.humidity); // strcat(buf1, text); memset(text, 0, sizeof(text)); sprintf(text, "Temp,%d;", temp++); strcat(buf1, text); memset(text, 0, sizeof(text)); sprintf(text, "Humi,%d;",humi++); strcat(buf1, text); sprintf(buf, "POST /devices/%s/datapoints?type=5 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\n" "Content-Length:%d\r\n\r\n", DEVID, APIKEY, strlen(buf1)); strcat(buf, buf1); } 2、从OneNET平台获取数据

这部分主要是为了获取开关的值,以此实现控制板子的LED灯 我的代码编写如下: 这个函数主要是从OneNET平台上获取数据流名为KEY的当前值,其中DEVID,Master_APIkey可以在OneNET平台上获取。 函数实现:

void OneNet_GetData(void) { char buf[256]; u8 len = 0; sprintf(buf,"GET http://api.heclouds.com/devices/%s/datapoints?datastream_id=KEY HTTP/1.1\r\n%s\r\nHost:api.heclouds.com\r\n\r\n",DEVID,Master_APIkey); len = strlen(buf); ESP8266_SendData((u8*)buf,len); }

函数调用: 在main函数中每隔1S调用一次OneNet_GetData()函数,保证能够及时响应命令。当服务器接收到数据包后就会回复数据流KEY的当前值给ESP8266。 在这里插入图片描述

3、下发命令的处理

在void OneNet_RevPro()函数里面添加控制代码,我添加的代码如下:

//当GET KEY的数据流时,服务器会下发这样的数据, ..,"value":"0"}],"id":"KEY"} if(strstr((char *)dataPtr, "\"value\":\"1\"")) { UsartPrintf(USART_DEBUG, "LED ON\r\n"); LED = 0; } else if(strstr((char *)dataPtr, "\"value\":\"0\"")) { UsartPrintf(USART_DEBUG, "LED OFF\r\n"); LED = 1; } ESP8266_Clear(); 五、手机APP制作

这部分主要讲如何制作手机APP来连OneNET平台,并且获取数据和下发命令控制LED灯。APP是使用E4A中文安卓编程开发的,编程思维和C语言很相似,并且是中文编程,只需一天就能基本掌握。

1、页面布局

由于时间原因,布局随意了点,大家有时间可以慢慢优化页面 在这里插入图片描述

2、连接OneNET云平台

主要用到了网络类主组件中的客户组件 在这里插入图片描述 我们选中这个组件,右击可以查看组件的命令,方法在单片机编程中相当于函数,事件相当于中断。 在这里插入图片描述 在提示信息中,我们可以清楚的看到连接服务器方法的用法。IP地址和端口号被我定义为全局变量,这在E4A中叫程序集变量。 在这里插入图片描述

3、查询数据流

查询按钮单击事件编写如下: 在E4A编程中单引号’ 是注释。在单击事件中,主要做的就是将需要发送到OneNET服务器的数据组装好,赋值给程序集变量客户请求数据,然后打开定时器事件。从上部分的串口助手连接OneNET服务器中,我们可以知道打包好的数据是干什么用的。

事件 查询按钮.被单击() 如果 查询按钮.标题 = "查询数据流" 则 查询按钮.标题 = "结束查询" '更改按钮标题 变量 子串1 为 文本型 变量 子串2 为 文本型 变量 子串3 为 文本型 变量 子串4 为 文本型 变量 子串5 为 文本型 子串1 = "GET /devices/" 子串2 = "/datapoints?datastream_id=" 子串3 = " HTTP/1.1\napi-key:" 子串4 = "Host:api.heclouds.com\n" 子串5 = "Connection:close\n\n" 'GET /devices/699063374/datapoints?datastream_id=Temp,Humi HTTP/1.1 'api-key:=08b33=G=KP8qxRoCYYrurN41yk= 'Host:api.heclouds.com 'Connection:close(后两回车) 客户端请求数据 = 子串1 & 设备ID框.内容 & 子串2 & 数据流名框1.内容 & "," & 数据流名框2.内容 & 子串3 & 密钥框.内容 & "\n" & 子串4 & 子串5 '弹出提示(客户端请求数据) 时钟1.时钟周期 = 3*1000 '开始定时中断3S 否则 时钟1.时钟周期 = 0 '关闭定时 查询按钮.标题 = "查询数据流" 结束 如果 结束 事件

时钟周期事件

事件 时钟1.周期事件() 客户1.连接服务器(IP地址,端口号,5000) 客户1.发送数据(文本到字节(客户端请求数据,"GBK")) '向服务器发送数据 '由于发送内容有Connection:close,故发送完断开连接 结束 事件

客户收到数据事件 当客户端发送刚刚的组装好的数据包后,服务器就会返回信息,这时就会触发客户收到数据事件 为了从服务器发过来的数据拿出想要的“温湿度值”,并且放在页面中对应的编辑框内,做如下处理:

事件 客户1.收到数据(数据 为 字节型()) 服务器数据 = 字节到文本(数据,"GBK") 接收框.内容 = 接收框.内容 & "\n" & "服务器:" & 服务器数据 '收到服务器发来的字节集数据,转换成文本 接收框.置光标位置(取文本长度(接收框.内容)) 如果 查询按钮.标题 = "结束查询" 则 '如果正在查询数据流,就执行下面 变量 分割数组 为 文本型() 变量 数据流数 为 文本型 变量 计次 为 整数型 变量 结果 为 整数型 变量 上传类型 为 整数型 '从服务器请求的数据如下 'type3 格式的数据 '{"errno":0,"data":{"count":2,"datastreams":[{"datapoints":[{"at":"2022-05-14 01:24:36.000","value":29}],"id":"Temp"},{"datapoints":[{"at":"2022-05-14 01:25:01.000","value":100}],"id":"Humi"}]},"error":"succ"} 'type5 格式的数据 '{"errno":0,"data":{"count":2,"datastreams":[{"datapoints":[{"at":"2022-05-13 22:43:48.030","value":"41"}],"id":"Temp"},{"datapoints":[{"at":"2022-05-13 22:43:48.032","value":"60"}],"id":"Humi"}]},"error":"succ"} 分割数组 = 分割文本(服务器数据,"value") '分割数组(1) = ":"89"}],"id":"Temp"},{"datapoints":[{"at":"2022-05-12 01:37:24.447"," '分割数组(2) = ":"45"}],"id":"Humi"}]},"error":"succ"} '读取数据流个数 数据流数 = 取指定文本2(分割数组(0),"count\":",",\"datastreams") 上传类型 = 寻找文本(服务器数据,"value\":\"",0) '如果找到了说明是type5上传的数据类型,否则是type3 如果 上传类型 = -1 则 '找不到 'type3格式数据 计次 = 1 '从下分割数组(1)开始循环查找 判断循环首 计次


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有